import cgi
import datamodel
import os
import sys
import xml.dom.minidom

from google.appengine.ext import db
from google.appengine.ext.db import BadKeyError
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from xml.dom.minidom import Element
from xml.dom.minidom import Node



class Init(webapp.RequestHandler):
  def get(self):
      self.response.headers['Content-Type'] = 'text/xml'
      
      db.delete(datamodel.Classifier.all())
      db.delete(datamodel.Item.all())
      db.delete(datamodel.Location.all())
      
      datamodel.Classifier(name='Het mooiste').put()
      datamodel.Classifier(name='Het lelijkste').put()
      datamodel.Classifier(name='Het slechtste').put()      
      datamodel.Classifier(name='Het beste').put()      
      
      datamodel.Classifier(name='De mooiste').put()
      datamodel.Classifier(name='De lelijkste').put()
      datamodel.Classifier(name='De slechtste').put()      
      datamodel.Classifier(name='De beste').put()
      
      self.response.out.write('<ok/>')

class Options(webapp.RequestHandler):
  def get(self):
      self.response.headers['Content-Type'] = 'text/xml'
      
      classifications = datamodel.Classifier.all()

      template_values = {
                         'classifications': classifications 
      }

      path = os.path.join(os.path.dirname(__file__), 'templates/options_template.tmpl')
      self.response.out.write(template.render(path, template_values))

class AddItem(webapp.RequestHandler):
    def post(self):
        self.response.headers['Content-Type'] = 'text/xml'
        
        data = self.request.get('data')
        
        doc = xml.dom.minidom.parseString(self.request.get('data'))                
        
        itemName = doc.getElementsByTagName('name')[0].childNodes[0].data
        itemType = doc.getElementsByTagName('type')[0].childNodes[0].data
        
        sys.stderr.write('itemName [' + itemName + '] itemType [' + itemType + ']')
               
        classifiers = datamodel.Classifier.gql('WHERE name=:type', type=itemType)
        itemClassifier = classifiers.get()
        
        if itemClassifier == None:
            self.response.out.write('<err>Unable to find a classifier with name [' + itemType + ']</err>')
            return           
        
        # Duplicate?
        qry = datamodel.Item.gql( "WHERE name=:item", item=itemName)
        if qry.fetch(1):
            self.response.out.write('<err>There is already an item with that name [' + itemName + ']</err>')
            return              
        
        i = datamodel.Item(name=itemName,
                           ip=os.environ['REMOTE_ADDR'],
                           creator=users.get_current_user(),
                           classifier=itemClassifier)
        i.put()
        
        self.response.out.write('<item id="' + str(i.key()) + '" type="' + i.classifier.name + '">')
        self.response.out.write('    <name>' + itemName + '</name>')
        self.response.out.write('</item>')

class AddVote(webapp.RequestHandler):
    def post(self):
        self.response.headers['Content-Type'] = 'text/xml'
        
        data = self.request.get('data')
        
        doc = xml.dom.minidom.parseString(self.request.get('data'))                
        
        locationId = doc.getElementsByTagName('location-id')[0].childNodes[0].data
        rating = doc.getElementsByTagName('rating')[0].childNodes[0].data
        
        sys.stderr.write('locationId [' + locationId + '] rating [' + rating + ']')        
        
        try:
            rating = int(rating)
        except ValueError:
            self.response.out.write('<err>Rating [' + rating +'] is not a valid integer</err>')
            return
        
        location = datamodel.Location.get(locationId)
        
        location.number_of_votes = location.number_of_votes + 1
        location.vote_total += int(rating)
        
        location.put()        

        self.response.out.write('<location id="' + str(location.key()) + '">')
        self.response.out.write('    <rating>' + str(location.rating()) + '</rating>')
        self.response.out.write('</location>')
        
class AddLocation(webapp.RequestHandler):
    def post(self):
        self.response.headers['Content-Type'] = 'text/xml'
        
        data = self.request.get('data')
        
        doc = xml.dom.minidom.parseString(self.request.get('data'))                
        
        itemId = doc.getElementsByTagName('item-id')[0].childNodes[0].data
        
        latitude = doc.getElementsByTagName('geo-data')[0].getElementsByTagName('latitude')[0].childNodes[0].data
        longitude = doc.getElementsByTagName('geo-data')[0].getElementsByTagName('longitude')[0].childNodes[0].data
        
        description = doc.getElementsByTagName('description')[0].childNodes[0].data
        
        sys.stderr.write('itemId [' + itemId + '] description [' + description + '] latitude [' + latitude + '] longitude [' + longitude + ']')

        try:
            item = datamodel.Item.get(itemId)
        except BadKeyError :
            self.response.out.write('<err>Illegal key [' + itemId + ']</err>')
            return

        if item == None:
            self.response.out.write('<err>Unable to find an item with key [' + itemId + ']</err>')
            return                    
        
        l = datamodel.Location(item=item,
                               description=description,
                               latitude=latitude,
                               longitude=longitude,
                               creator=users.get_current_user())
        l.put()
        
        self.response.out.write('<location id="' + str(l.key()) + '">')
        self.response.out.write('    <item-id>' + itemId + '</item-id>')
        self.response.out.write('    <description>' + l.description + '</description>')
        self.response.out.write('    <rating>0</rating>')
        self.response.out.write('    <geo-data>')
        self.response.out.write('        <latitude>' + l.latitude + '</latitude>')
        self.response.out.write('        <longitude>' + l.longitude + '</longitude>')
        self.response.out.write('    </geo-data>')
        self.response.out.write('</location>')             
        
class Query(webapp.RequestHandler):
    def post(self):
        self.response.headers['Content-Type'] = 'text/xml'
        
        data = self.request.get('data')
        
        doc = xml.dom.minidom.parseString(self.request.get('data'))                
        
        itemId = doc.getElementsByTagName('item-id')[0].childNodes[0].data      

        try:
            item = datamodel.Item.get(itemId)
        except BadKeyError :
            self.response.out.write('<err>Illegal key [' + itemId + ']</err>')
            return
        
        if item == None:
            self.response.out.write('<err>Unable to find an item with key [' + itemId + ']</err>')
            return

        template_values = {
                         'item': item 
        }

        path = os.path.join(os.path.dirname(__file__), 'templates/results_template.tmpl')
        self.response.out.write(template.render(path, template_values))
             
application = webapp.WSGIApplication(
                                     [(r'/services/init.*', Init),
                                      (r'/services/options.*', Options),
                                      (r'/services/item.*', AddItem),
                                      (r'/services/vote.*', AddVote),
                                      (r'/services/location.*', AddLocation),
                                      (r'/services/query.*', Query)],
                                     debug=True)

def main():
  run_wsgi_app(application)

